package com.cke.yang.security.app.service.impl;

import com.cke.yang.common.infra.enums.SaveActionEnum;
import com.cke.yang.common.domain.model.SecUserDetails;
import com.cke.yang.common.infra.utils.PageUtils;
import com.cke.yang.security.api.dto.request.SecUserListRequest;
import com.cke.yang.security.app.service.SecRoleService;
import com.cke.yang.security.app.service.SecUserService;
import com.cke.yang.security.domain.entity.SecRole;
import com.cke.yang.security.domain.entity.SecUser;
import com.cke.yang.security.domain.repository.SecUserRepository;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用户服务类
 *
 * @author yuyang
 */
@Slf4j
@Service
public class SecUserServiceImpl implements SecUserService {

    @Autowired
    private SecUserRepository secUserRepository;
    @Autowired
    private SecRoleService secRoleService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public PageInfo<SecUser> list(Pageable page, SecUserListRequest param) {
        return PageUtils.doPage(page, () -> {
                    List<SecUser> userList = this.secUserRepository.list(param);
                    userList.forEach(x -> x.setPassword(null));
                });
    }

    @Override
    public List<SecUser> save(List<SecUser> secUserList) {
        if (CollectionUtils.isEmpty(secUserList)) {
            return List.of();
        }
        for (SecUser secUser : secUserList) {
            String action = secUser.get$action();
            // action 校验
            if ( ! SaveActionEnum.support(action)) {
                continue;
            }
            // action转换成Enum对象
            SaveActionEnum actionEnum = SaveActionEnum.getByCode(action);
            if (Objects.isNull(actionEnum)) {
                continue;
            }
            this.secUserRepository.save(actionEnum, secUser);
        }
        return secUserList;
    }

    @Override
    public Object self() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !(authentication.getPrincipal() instanceof SecUserDetails userDetails)) {
            return null;
        }

        // 从数据库中根据userId读取用户数据，将昵称之类的字段也填充进返回结果里
        SecUser dbUser = this.secUserRepository.findById(userDetails.getUserId());
        if (dbUser == null) {
            return null;
        }

        // 构建包含完整用户信息的数据
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", dbUser.getUserId());
        userInfo.put("username", dbUser.getUsername());
        userInfo.put("nickName", dbUser.getNickName());
        userInfo.put("realName", dbUser.getRealName());
        userInfo.put("sex", dbUser.getSex());
        userInfo.put("email", dbUser.getEmail());
        userInfo.put("phone", dbUser.getPhone());
        userInfo.put("avatar", dbUser.getAvatar());
        userInfo.put("enabled", dbUser.getIsEnabled());
        userInfo.put("defaultRoleId", dbUser.getDefaultRoleId());
        userInfo.put("lastLoginAt", dbUser.getLastLoginAt());
        userInfo.put("currentRoleId", userDetails.getCurrentRoleId());
        userInfo.put("currentRoleName", userDetails.getCurrentRoleName());

        // 如果当前角色信息为空，尝试获取当前角色
        if (userDetails.getCurrentRoleId() == null || userDetails.getCurrentRoleName() == null) {
            SecRole currentRole = secRoleService.getCurrentRole();
            if (currentRole != null) {
                userInfo.put("currentRoleId", currentRole.getRoleId());
                userInfo.put("currentRoleName", currentRole.getRoleName());
            }
        }
        
        log.debug("返回用户信息: userId={}, username={}, nickName={}, currentRoleId={}, currentRoleName={}",
                dbUser.getUserId(), dbUser.getUsername(), dbUser.getNickName(),
                userInfo.get("currentRoleId"), userInfo.get("currentRoleName"));

        return userInfo;
    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {
        // 获取当前登录用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !(authentication.getPrincipal() instanceof SecUserDetails userDetails)) {
            throw new RuntimeException("用户未登录");
        }

        // 从数据库获取用户信息
        SecUser dbUser = this.secUserRepository.findById(userDetails.getUserId());
        if (dbUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, dbUser.getPassword())) {
            throw new RuntimeException("旧密码不正确");
        }

        // 更新密码
        this.secUserRepository.updatePassword(dbUser.getUserId(), passwordEncoder.encode(newPassword));

        log.info("用户 {} 修改密码成功", dbUser.getUsername());
    }

}
